package com.open.capacity.reimburse.service.impl;

import com.open.capacity.commons.Result;
import com.open.capacity.model.system.LoginAppUser;
import com.open.capacity.model.system.SysUser;
import com.open.capacity.reimburse.dao.BillProjectApplyDetailDao;
import com.open.capacity.reimburse.dao.BillProjectApplyTargetDao;
import com.open.capacity.reimburse.entity.*;
import com.open.capacity.reimburse.exception.BusinessException;
import com.open.capacity.reimburse.util.uuid.UUIDUtils;
import com.open.capacity.user.model.SysDepartment;
import com.open.capacity.user.service.SysDepartmentService;
import com.open.capacity.user.service.SysUserService;
import com.open.capacity.utils.SysUserUtil;
import com.open.capacity.workflow.model.WFEngine.WFContent;
import com.open.capacity.workflow.model.WFProcessinstance;
import com.open.capacity.workflow.model.WFTask;
import com.open.capacity.workflow.service.WFEngineService;
import com.open.capacity.workflow.service.WFProcessinstanceService;
import com.open.capacity.workflow.service.WFTaskService;
import com.open.capacity.workflow.vo.WFParameter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.open.capacity.commons.PageResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.open.capacity.commons.CodeEnum;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.MapUtils;

import com.open.capacity.reimburse.dao.BillProjectApplyDao;
import com.open.capacity.reimburse.service.BillProjectApplyService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;


@Service
public class BillProjectApplyServiceImpl implements BillProjectApplyService {

    @Autowired
    private BillProjectApplyDao billDao;
    @Autowired
    private BillProjectApplyDetailDao detailDao;
    @Autowired
    private BillProjectApplyTargetDao targetDao;
    @Autowired
    private WFProcessinstanceService processinstanceService;
    @Autowired
    private WFEngineService engineService;
    @Autowired
    private WFTaskService taskService;

    @Autowired
    private SysUserService userService;
    @Autowired
    private SysDepartmentService departmentService;


    /**
     * 添加
     *
     * @param bill
     */
    @Transactional(rollbackFor = Exception.class)
    public int save(BillProjectApply bill) {
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        if (StringUtils.isEmpty(bill.getId())) {
            bill.setId(UUIDUtils.getOriginalUUIDWithoutBar());
        }
        bill.setStatus(1);
        bill.setCreateTime(new Date());
        bill.setCreateUserid(loginUser.getId());
        bill.setCreateUsername(loginUser.getRealName());

        if (CollectionUtils.isNotEmpty(bill.getDetails())) {
            for (BillProjectApplyDetail item : bill.getDetails()) {
                item.setId(UUIDUtils.getOriginalUUIDWithoutBar());
                item.setRefId(bill.getId());
                detailDao.save(item);
            }
        }

        if (CollectionUtils.isNotEmpty(bill.getTargets())) {
            for (BillProjectApplyTarget item : bill.getTargets()) {
                item.setId(UUIDUtils.getOriginalUUIDWithoutBar());
                item.setRefId(bill.getId());
                targetDao.save(item);
            }
        }

        int count = billDao.save(bill);
        return count;
    }

    /**
     * 修改
     *
     * @param bill
     */
    @Transactional(rollbackFor = Exception.class)
    public int update(BillProjectApply bill) {
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();
        bill.setCreateTime(new Date());
        bill.setCreateUserid(loginUser.getId());
        bill.setCreateUsername(loginUser.getRealName());

        detailDao.deleteByRefId(bill.getId());
        for (BillProjectApplyDetail item : bill.getDetails()) {
            item.setId(UUIDUtils.getOriginalUUIDWithoutBar());
            item.setRefId(bill.getId());
            detailDao.save(item);
        }

        targetDao.deleteByRefId(bill.getId());
        for (BillProjectApplyTarget item : bill.getTargets()) {
            item.setId(UUIDUtils.getOriginalUUIDWithoutBar());
            item.setRefId(bill.getId());
            targetDao.save(item);
        }

        int count = billDao.update(bill);
        return count;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<WFContent> send(Boolean isNew, String processId, String schemeCode, String processName, Integer processLevel, String description, String auditors, String formData) {
        WFParameter parameter = new WFParameter();
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();

        parameter.setCompanyId(loginUser.getCompanyId());
        parameter.setDepartmentId(loginUser.getDepartmentId());
        parameter.setUserId(loginUser.getId());
        parameter.setUserName(loginUser.getRealName());
        parameter.setIsNew(isNew);
        parameter.setProcessId(processId);
        parameter.setSchemeCode(schemeCode);
        parameter.setProcessName(processName);
        parameter.setProcessLevel(processLevel);
        parameter.setAuditors(auditors);
        parameter.setFormData(formData);
        parameter.setDescription(description);

        billDao.updateStatus(processId, 2);

        Result<WFContent> res = engineService.create(parameter);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cancel(String processId) {
        billDao.updateStatus(processId, 1);
        processinstanceService.updateStatus(processId, -1);
        return 1;
    }


    /**
     * 删除
     *
     * @param id
     */
    public int delete(String id) {
        return billDao.delete(id);
    }

    /**
     * 查询记录
     *
     * @param id
     * @return
     */
    public BillProjectApply findById(String id) {
        BillProjectApply bill = billDao.findById(id);
        if (bill != null) {
            WFProcessinstance processinstance = processinstanceService.findById(id);
            bill.setProcessCode(processinstance != null ? processinstance.getCode() : null);
            bill.setDetails(detailDao.findByRefId(id));
            bill.setTargets(targetDao.findByRefId(id));
        }
        return bill;
    }

    /**
     * 分页
     *
     * @param params
     * @return
     */
    public PageResult<BillProjectApply> pageAll(Map<String, Object> params) {
        //设置分页信息，分别是当前页数和每页显示的总记录数【记住：必须在mapper接口中的方法执行之前设置该分页信息】
        if (MapUtils.getInteger(params, "page") != null && MapUtils.getInteger(params, "limit") != null)
            PageHelper.startPage(MapUtils.getInteger(params, "page"), MapUtils.getInteger(params, "limit"), true);

        List<BillProjectApply> list = billDao.findAll(params);
        list.forEach(item -> {
            List<WFTask> tasks = taskService.findTasksByProcessId(item.getId());
            if (tasks.stream().filter(t -> t.getIsFinished() == 1).findFirst().isPresent()) {
                item.setIsStart(1);
            } else {
                item.setIsStart(0);
            }
        });

        PageInfo<BillProjectApply> pageInfo = new PageInfo(list);

        return PageResult.<BillProjectApply>builder().data(pageInfo.getList()).resp_code(CodeEnum.SUCCESS.getCode()).count(pageInfo.getTotal()).build();
    }

    /**
     * 列表
     *
     * @param params
     * @return
     */
    public List<BillProjectApply> findAll(Map<String, Object> params) {
        return billDao.findAll(params);
    }

}
